﻿/*=====================================================================
  
    File:      TabularDatabase.Hierarchy.cs

    Summary:   This is the class that implements all related functionality 
               around Hierarchies in a tabular model, for all TabularDatabase 
               commandlets.
 
               Tabular Database Cmdlets (TabularDatabaseCmdlets) is sample code 
               to show and explain how to use the AMO to Tabular (AMO2Tabular)
               library to build a PowerShell library of cmdlets to manage 
               Tabular model objects. 
               The sample can be seen as a sample library of cmdlets
               with the necessary code to execute each particular 
               action or operation over a logical tabular object. 

    Authors:   JuanPablo Jofre (jpjofre@microsoft.com)
    Date:	   04-Apr-2012
  
    Change history:

    @TODO: 
  
-----------------------------------------------------------------------
  
    This file is part of the Microsoft SQL Server Code Samples.
    Copyright (C) Microsoft Corporation.  All rights reserved.
  
  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  
  
  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF 
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
  
======================================================================*/


using System;
using System.Globalization;
using System.Management.Automation;     //  Windows PowerShell assembly.
using MicrosoftSql2012Samples.Amo2Tabular;
using MicrosoftSql2012Samples.TabularDatabaseCmdlet.Properties;
using AMO = Microsoft.AnalysisServices;

namespace MicrosoftSql2012Samples.TabularDatabaseCmdlet
{
    [Cmdlet(VerbsCommon.Add, "HierarchyToTabularTable")]
    public class AddHierarchyToTabularTable : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string hierarchyName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string[] DefiningColumnNames { get; set; }

        [Parameter(Mandatory = false, Position = 5)]
        [ValidateNotNullOrEmpty]
        public string[] LevelNames { get; set; }


        // Overide the ProcessRecord method to add a Hierarchy
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                //  -   Number of Defining Columns must match number of Level Names 
                //  -   OR, Level Names must be omitted

                if((LevelNames!=null) && (LevelNames.Length != DefiningColumnNames.Length))
                {
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.UnmatchedNumberOfHierarchyDefiningColumnsAndLevelNamesArgumentException)), string.Empty, ErrorCategory.InvalidArgument, null));
                }

                LevelInfo[] hierarchyLevelsInfo = new LevelInfo[DefiningColumnNames.Length];
                for (int i = 0; i < DefiningColumnNames.Length; i++)
                {
                    hierarchyLevelsInfo[i] = new LevelInfo(DefiningColumnNames[i], (LevelNames != null ? LevelNames[i] : DefiningColumnNames[i]));
                }
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.HierarchyAdd(database, tableName, hierarchyName, true, hierarchyLevelsInfo);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddHierarchyToTabularTableWriteReport, hierarchyName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularFirstTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Add, "LevelsToTabularHierarchy")]
    public class AddLevelsToTabularHierarchy : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string hierarchyName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string[] DefiningColumnNames { get; set; }

        [Parameter(Mandatory = false, Position = 5)]
        [ValidateNotNullOrEmpty]
        public string[] LevelNames { get; set; }


        // Overide the ProcessRecord method to add a Levels to an existing hierarchy
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                //  -   Number of Defining Columns must match number of Level Names 
                //  -   OR, Level Names must be omitted

                if ((LevelNames != null) && (LevelNames.Length != DefiningColumnNames.Length))
                {
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.UnmatchedNumberOfHierarchyDefiningColumnsAndLevelNamesArgumentException)), string.Empty, ErrorCategory.InvalidArgument, null));
                }

                LevelInfo[] hierarchyLevelsInfo = new LevelInfo[DefiningColumnNames.Length];
                for (int i = 0; i < DefiningColumnNames.Length; i++)
                {
                    hierarchyLevelsInfo[i] = new LevelInfo(DefiningColumnNames[i], (LevelNames != null ? LevelNames[i] : DefiningColumnNames[i]));
                }
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.HierarchyAlterLevelsAdd(database, tableName, hierarchyName, true, hierarchyLevelsInfo);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddLevelsToTabularHierarchyWriteReport, hierarchyName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Add, "LevelToTabularHierarchy")]
    public class AddLevelToTabularHierarchy : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string hierarchyName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string definingColumnName { get; set; }

        [Parameter(Mandatory = false, Position = 5)]
        [ValidateNotNullOrEmpty]
        public string levelName { get; set; }


        // Overide the ProcessRecord method to add a Levels to an existing hierarchy
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                if (levelName == null)
                {
                    levelName = definingColumnName;
                }
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.HierarchyAlterLevelAdd(database, tableName, hierarchyName, definingColumnName, levelName, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddLevelToTabularHierarchyWriteReport, hierarchyName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Get, "HierarchiesInTabularTable")]
    public class GetHierarchiesInTabularTable : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        // Overide the ProcessRecord method to Get all Calculated Column names
        // using the supplied server name, database name and table
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        foreach (string hierarchyName in AMO2Tabular.HierarchiesEnumerate(database, tableName))
                        {
                            WriteObject(hierarchyName, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

}
